home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / fsovl / dos.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  9KB  |  403 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  DOS.C
  9.  */
  10.  
  11. #include "defs.h"
  12.  
  13. Prototype void ReturnPacket(DosPacket *packet);
  14. Prototype FileLock *MakeDosFileLock(GEntry *gentry, long mode);
  15. Prototype void FreeDosFileLock(FileLock *flock);
  16. Prototype void *DosAlloc(long bytes);
  17. Prototype void DosFree(void *ptr);
  18. Prototype long RoutePacket(DosPacket *packet);
  19. Prototype GEntry *BLockToGEntry(BPTR lock);
  20. Prototype MsgPort *BLockToGPort(BPTR lock);
  21. Prototype BPTR BLockToGLock(BPTR lock);
  22. Prototype ubyte *BNameToPtr(BPTR bname, short *plen);
  23. Prototype long DoSyncPacket(MsgPort *, long, long, long, long, long);
  24.  
  25. Prototype BPTR LockPacket(BPTR lock, ubyte *name, short nameLen);
  26. Prototype BPTR DupLockPacket(BPTR lock);
  27. Prototype BPTR CreateDirPacket(BPTR lock, ubyte *name, short nameLen);
  28. Prototype BPTR LockPacketPort(MsgPort *port, ubyte *name, short nameLen);
  29. Prototype void UnLockPacket(BPTR lock);
  30. Prototype BPTR OpenPacket(BPTR lock, ubyte *name, short nameLen, long mode);
  31. Prototype void ClosePacket(BPTR fhb);
  32. Prototype void SetCommentPacket(BPTR, ubyte *,short, ubyte *,short, GEntry *);
  33. Prototype void ExaminePacket(BPTR lock, FileInfoBlock *fib);
  34. Prototype long ReadPacket(BPTR fhb, ubyte *buf, long bytes);
  35. Prototype long WritePacket(BPTR fhb, ubyte *buf, long bytes);
  36.  
  37. Prototype void makebstr(ubyte *name, short nameLen, ubyte *buf);
  38.  
  39. void
  40. ReturnPacket(DosPacket *packet)
  41. {
  42.     Message *mess;
  43.     MsgPort *replyPort;
  44.  
  45.     replyPort             = packet->dp_Port;
  46.     mess             = packet->dp_Link;
  47.     packet->dp_Port         = PktPort;
  48.     mess->mn_Node.ln_Name    = (char *)packet;
  49.     PutMsg(replyPort, mess);
  50. }
  51.  
  52. FileLock *
  53. MakeDosFileLock(GEntry *gentry, long mode)
  54. {
  55.     FileLock *flock;
  56.  
  57.     if (flock = DosAlloc(sizeof(FileLock))) {
  58.     flock->fl_Key = (long)gentry;
  59.     flock->fl_Access = mode;
  60.     flock->fl_Task = PktPort;
  61.     flock->fl_Volume = CTOB(Dl);
  62.     }
  63.     return(flock);
  64. }
  65.  
  66. void
  67. FreeDosFileLock(FileLock *flock)
  68. {
  69.     DosFree(flock);
  70. }
  71.  
  72. void *
  73. DosAlloc(long bytes)
  74. {
  75.     long *pl;
  76.  
  77.     bytes += 4;
  78.  
  79.     if (pl = AllocMem(bytes, MEMF_PUBLIC|MEMF_CLEAR)) {
  80.     *pl = bytes;
  81.     }
  82.     return((void *)(pl + 1));
  83. }
  84.  
  85. void
  86. DosFree(void *ptr)
  87. {
  88.     long *pl = (long *)ptr - 1;
  89.     FreeMem(pl, *pl);
  90. }
  91.  
  92. /*
  93.  * Route the specified packet to the underlying filesystem after making
  94.  * appropriate modifications (convert our locks to their locks, etc...),
  95.  * and wait for a response.
  96.  *
  97.  * Returns a negative error code if an error occurs, else returns Res1
  98.  */
  99.  
  100. long 
  101. RoutePacket(DosPacket *packet)
  102. {
  103.     long r;
  104.  
  105.     switch(packet->dp_Type) {
  106.     case ACTION_EXAMINE_OBJECT:        /* dp_Arg1 = lock    */
  107.     case ACTION_EXAMINE_NEXT:
  108.     case ACTION_DELETE_OBJECT:
  109.     case ACTION_CREATE_DIR:
  110.     r = DoSyncPacket(
  111.         BLockToGPort(packet->dp_Arg1),
  112.         packet->dp_Type,
  113.         BLockToGLock(packet->dp_Arg1),
  114.         packet->dp_Arg2,
  115.         packet->dp_Arg3,
  116.         packet->dp_Arg4
  117.     );
  118.     break;
  119.     case ACTION_SET_DATE:        /* dp_arg2 = lock    */
  120.     case ACTION_SET_PROTECT:
  121.     case ACTION_SET_COMMENT:
  122.     r = DoSyncPacket(
  123.         BLockToGPort(packet->dp_Arg2),
  124.         packet->dp_Type,
  125.         packet->dp_Arg1,
  126.         BLockToGLock(packet->dp_Arg2),
  127.         packet->dp_Arg3,
  128.         packet->dp_Arg4
  129.     );
  130.     break;
  131.     case ACTION_RENAME_OBJECT:        /* dp_Arg1, Arg3 = lock    */
  132.     r = DoSyncPacket(
  133.         BLockToGPort(packet->dp_Arg1),
  134.         packet->dp_Type,
  135.         BLockToGLock(packet->dp_Arg1),
  136.         packet->dp_Arg2,
  137.         BLockToGLock(packet->dp_Arg3),
  138.         packet->dp_Arg4
  139.     );
  140.     break;
  141.     case ACTION_CHANGE_MODE:        /* dp_Arg2 GHandle    */
  142.     /* no action */
  143.     r = 0;
  144.     break;
  145.     }
  146.     return(r);
  147. }
  148.  
  149. ubyte *
  150. BNameToPtr(BPTR bname, short *plen)
  151. {
  152.     ubyte *ptr = BTOC(bname);
  153.  
  154.     *plen = *ptr;
  155.     return(ptr + 1);
  156. }
  157.  
  158. GEntry *
  159. BLockToGEntry(BPTR lock)
  160. {
  161.     FileLock *flock;
  162.     GEntry *gentry;
  163.  
  164.     if (flock = BTOC(lock)) {
  165.     gentry = (GEntry *)flock->fl_Key;
  166.     } else {
  167.     gentry = &GRoot;
  168.     }
  169.     return(gentry);
  170. }
  171.  
  172. MsgPort *
  173. BLockToGPort(BPTR lock)
  174. {
  175.     FileLock *flock = BTOC(BLockToGEntry(lock)->ge_Lock);
  176.     return(flock->fl_Task);
  177. }
  178.  
  179. BPTR
  180. BLockToGLock(BPTR lock)
  181. {
  182.     return(BLockToGEntry(lock)->ge_Lock);
  183. }
  184.  
  185. /*
  186.  * Synchronous Packet
  187.  */
  188.  
  189. long
  190. DoSyncPacket(MsgPort *dport, long action, long a1, long a2, long a3, long a4)
  191. {
  192.     __aligned StdPacket std;
  193.  
  194.     clrmem(&std, sizeof(std));
  195.  
  196.     std.sp_Msg.mn_Node.ln_Name = (char *)&std.sp_Pkt;
  197.     std.sp_Pkt.dp_Link = &std.sp_Msg;
  198.     std.sp_Pkt.dp_Port = AuxPort;
  199.     std.sp_Pkt.dp_Type = action;
  200.     std.sp_Pkt.dp_Arg1 = a1;
  201.     std.sp_Pkt.dp_Arg2 = a2;
  202.     std.sp_Pkt.dp_Arg3 = a3;
  203.     std.sp_Pkt.dp_Arg4 = a4;
  204.  
  205.     dbprintf(("DoSynchPacket to %08lx type %08lx (%d) args %lx %lx %lx %lx\n",
  206.     dport, std.sp_Pkt.dp_Type, std.sp_Pkt.dp_Type,
  207.     std.sp_Pkt.dp_Arg1,
  208.     std.sp_Pkt.dp_Arg2,
  209.     std.sp_Pkt.dp_Arg3,
  210.     std.sp_Pkt.dp_Arg4
  211.     ));
  212.  
  213.     PutMsg(dport, &std.sp_Msg);
  214.     WaitPort(AuxPort);
  215.     GetMsg(AuxPort);
  216.  
  217.     dbprintf(("Res1 %08lx Res2 %08lx\n", 
  218.     std.sp_Pkt.dp_Res1, 
  219.     std.sp_Pkt.dp_Res2
  220.     ));
  221.  
  222.     if (std.sp_Pkt.dp_Res1 == DOS_FALSE)
  223.     return(-std.sp_Pkt.dp_Res2);
  224.     /*
  225.     if (std.sp_Pkt.dp_Res2 > 0)
  226.     return(-std.sp_Pkt.dp_Res2);
  227.     */
  228.     return(std.sp_Pkt.dp_Res1);
  229. }
  230.  
  231. /*
  232.  * Manual Packets
  233.  */
  234.  
  235. BPTR 
  236. LockPacket(BPTR lock, ubyte *name, short nameLen)
  237. {
  238.     FileLock *flock = BTOC(lock);
  239.     long r;
  240.     __aligned char buf[128];
  241.  
  242.     makebstr(name, nameLen, buf);
  243.     if ((long)buf & 3)
  244.     dbprintf(("BUF NOT ALIGNED\n"));
  245.  
  246.     r = DoSyncPacket(
  247.     flock->fl_Task, ACTION_LOCATE_OBJECT, 
  248.     lock, CTOB(buf), SHARED_LOCK, 
  249.     0
  250.     );
  251.     if (r <= 0)
  252.     r = 0;
  253.     return(r);
  254. }
  255.  
  256. BPTR
  257. DupLockPacket(BPTR lock)
  258. {
  259.     FileLock *flock = BTOC(lock);
  260.     long r;
  261.  
  262.     r = DoSyncPacket(flock->fl_Task, ACTION_COPY_DIR, lock, 0, 0, 0);
  263.     if (r <= 0)
  264.     r = 0;
  265.     return(r);
  266. }
  267.  
  268. BPTR 
  269. CreateDirPacket(BPTR lock, ubyte *name, short nameLen)
  270. {
  271.     FileLock *flock = BTOC(lock);
  272.     long r;
  273.     __aligned char buf[128];
  274.  
  275.     makebstr(name, nameLen, buf);
  276.  
  277.     r = DoSyncPacket(
  278.     flock->fl_Task, ACTION_CREATE_DIR, 
  279.     lock, CTOB(buf), 0, 0
  280.     );
  281.     if (r <= 0)
  282.     r = 0;
  283.     return(r);
  284. }
  285.  
  286. BPTR 
  287. LockPacketPort(MsgPort *port, ubyte *name, short nameLen)
  288. {
  289.     long r;
  290.     __aligned char buf[128];
  291.  
  292.     makebstr(name, nameLen, buf);
  293.  
  294.     r = DoSyncPacket(
  295.     port, ACTION_LOCATE_OBJECT, 
  296.     0, CTOB(buf), SHARED_LOCK, 
  297.     0
  298.     );
  299.     if (r <= 0)
  300.     r = 0;
  301.     return(r);
  302. }
  303.  
  304. void 
  305. SetCommentPacket(BPTR lck,ubyte *np,short nl,ubyte *cp,short cl,GEntry *gentry)
  306. {
  307.     FileLock *flock = BTOC(lck);
  308.     __aligned char buf[128];
  309.     __aligned char cmm[128];
  310.  
  311.     makebstr(np, nl, buf);
  312.  
  313.     if (gentry && (gentry->ge_Flags & GEF_COMPRESSED))
  314.     cmm[0] = sprintf(cmm + 1, "##%08lx##%.*s", gentry->ge_Bytes, cl, cp);
  315.     else
  316.     cmm[0] = sprintf(cmm + 1, "%.*s", cl, cp);
  317.  
  318.     DoSyncPacket(flock->fl_Task, ACTION_SET_COMMENT,
  319.     0, lck, CTOB(buf), CTOB(cmm)
  320.     );
  321. }
  322.  
  323. void 
  324. UnLockPacket(BPTR lock)
  325. {
  326.     FileLock *flock = BTOC(lock);
  327.  
  328.     DoSyncPacket(flock->fl_Task, ACTION_FREE_LOCK, lock, 0, 0, 0);
  329. }
  330.  
  331. BPTR 
  332. OpenPacket(BPTR lock, ubyte *name, short nameLen, long mode)
  333. {
  334.     FileHandle *fh = DosAlloc(sizeof(FileHandle));
  335.     FileLock *flock = BTOC(lock);
  336.     __aligned char buf[128];
  337.     long r;
  338.  
  339.     dbprintf(("open: %d '%.*s'\n", mode, nameLen, name));
  340.  
  341.     makebstr(name, nameLen, buf);
  342.  
  343.     fh->fh_Port = (MsgPort *)DOS_FALSE;
  344.     fh->fh_Type = flock->fl_Task;
  345.     r = DoSyncPacket(flock->fl_Task, mode, CTOB(fh), lock, CTOB(buf), 0);
  346.     if (r != DOS_TRUE) {
  347.     DosFree(fh);
  348.     return(0);
  349.     } else {
  350.     dbprintf(("open success fh=%08lx arg1=%08lx\n", fh, fh->fh_Arg1));
  351.     return(CTOB(fh));
  352.     }
  353. }
  354.  
  355. void 
  356. ClosePacket(BPTR fhb)
  357. {
  358.     FileHandle *fh = BTOC(fhb);
  359.  
  360.     DoSyncPacket(fh->fh_Type, ACTION_END, fh->fh_Arg1, 0, 0, 0);
  361.     DosFree(fh);
  362. }
  363.  
  364. void 
  365. ExaminePacket(BPTR lock, FileInfoBlock *fib)
  366. {
  367.     FileLock *flock = BTOC(lock);
  368.  
  369.     DoSyncPacket(flock->fl_Task, ACTION_EXAMINE_OBJECT, lock, CTOB(fib), 0, 0);
  370. }
  371.  
  372. long 
  373. ReadPacket(BPTR fhb, ubyte *buf, long bytes)
  374. {
  375.     FileHandle *fh = BTOC(fhb);
  376.     long r;
  377.  
  378.     if (fh->fh_Type == 0)
  379.     return(0);
  380.     r = DoSyncPacket(fh->fh_Type, ACTION_READ, fh->fh_Arg1,(long)buf,bytes,0);
  381.     return(r);
  382. }
  383.  
  384. long 
  385. WritePacket(BPTR fhb, ubyte *buf, long bytes)
  386. {
  387.     FileHandle *fh = BTOC(fhb);
  388.     long r;
  389.  
  390.     r = DoSyncPacket(fh->fh_Type, ACTION_WRITE,fh->fh_Arg1,(long)buf,bytes,0);
  391.     return(r);
  392. }
  393.  
  394. void
  395. makebstr(ubyte *name, short nameLen, ubyte *buf)
  396. {
  397.     *buf = nameLen;
  398.     ++buf;
  399.     movmem(name, buf, nameLen);
  400.     buf[nameLen] = 0;        // necessary for 1.3
  401. }
  402.  
  403.